package la.iok.hzsvn.lewin.movie.operation.service;

import la.iok.hzsvn.lewin.movie.core.exception.ErrorCode;
import la.iok.hzsvn.lewin.movie.operation.entity.Wallet;
import la.iok.hzsvn.lewin.movie.operation.mapper.WalletMapper;
import la.iok.hzsvn.lewin.mybatis.service.BaseServiceImpl;
import la.iok.hzsvn.share.annotations.Nullable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class WalletServiceImpl extends BaseServiceImpl<Wallet, WalletMapper, Long> implements WalletService {
    public WalletServiceImpl(WalletMapper mapper) {
        super(mapper);
    }

    @Transactional
    @Override
    public void charge(@Nullable Long userId, @Nullable Integer amount) {
        ErrorCode.PROPERTY_CHECK_ERROR.assertNotNull(amount,"金额","金额不能为空");
        ErrorCode.PROPERTY_CHECK_ERROR.assertNotNull(userId,"用户id","用户id不能为空");
        ErrorCode.PROPERTY_CHECK_ERROR.assertTrue(amount != 0,"金额","金额不能为0");
        ErrorCode.PROPERTY_CHECK_ERROR.assertTrue(userId > 0,"用户id","用户id必须大于0");
        Wallet account = select("userId", userId);
        if(account == null){
            account = new Wallet();
            account.setBalance(amount);
            account.setUserId(userId);
            insertSelective(account);
            return;
        }
        int c = mapper.charge(account.getId(),account.getVersion(),amount);
        if(c != 1){
            //重试一次。可能被其他人刚刚并发修改了数据
            account = select("userId", userId);
            ErrorCode.FINANCIAL_CHANGE_ERROR.assertNotNull(account);
            c = mapper.charge(account.getId(),account.getVersion(),amount);
            ErrorCode.FINANCIAL_CHANGE_ERROR.assertEqual(1,c);
        }
    }

    @Override
    public int cost(Long userId, Integer amount, Long version) {
        if(userId == null || amount == null || version == null){
            return 0;
        }
        return mapper.cost(userId,amount,version);
    }

    @Override
    public Wallet wallet(Long userId) {
        if(userId == null){
            return null;
        }
        Wallet account = select("userId",userId);
        if(account == null){
            account = new Wallet();
            account.setUserId(userId);
            insertSelective(account);
            return select("userId",userId);
        }else{
            return account;
        }
    }
}
